//+-----------------------------+ //|Shashi RSI-R2 from Shell_20b | //+-----------------------------+ #property copyright "Ron Thompson" #property link "http://www.ForexMT4.com/" // This EA is NEVER to be SOLD individually // This EA is NEVER to be INCLUDED as part of a collection that is SOLD // user input extern bool WithTrend = false ; extern string Pairs = "AUDJPY,AUDNZD,AUDUSD,CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURUSD,GBPCHF,GBPJPY,GBPUSD,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY" ; extern double Lots = 0.2 ; extern double ProfitMade = 130 ; extern double LossLimit = 100 ; extern double BreakEven = 0 ; extern double TrailStop = 0 ; extern bool KillLogging = true ; // MULTI Pair handling // hard coded to use current symbol() for testing string Pairz[100]; static bool TradeAllowed[100]; static datetime bartime[100]; int ptrPMAX; int ptrPairz=0; string mySymbol; double bid; double ask; // Trade control double myPoint; // support for 3/5 decimal places int Slippage=2; // how many pips of slippage can you tolorate int loopcount; // count of order attempts int maxloop=20; // maximum number of attempts to handle errors int LL2SL=50; // LossLimit to StopLoss server spread int MagicNumber = 142538004; // allows multiple experts to trade on same account string TradeComment = "_ShashiM1d.txt"; // where to log information // Statistics int maxOrders; // statistic for maximum numbers or orders open at one time // used for verbose error logging #include //+-------------+ //| Custom init | //|-------------+ // Called ONCE when EA is added to chart or recompiled int init() { int OPS=0; int i; int cnt; // trades turned on only if there is NO open order // MULTIPLE order systems may need to change this for (i=0; i<100; i++) { mySymbol=Pairz[i]; OPS=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OPS++; } if(OPS==0) TradeAllowed[i]=true; else TradeAllowed[i]=false; }//for // Split the user string into an array int ipair=0; int pcomma=0; int comma=0; //clear the array for (i=0; i<100; i++) { Pairz[i]=""; } while (true) { // if backtesting then set array to current symbol only if(IsTesting()) { Pairz[0]=Symbol(); ptrPMAX=1; break; } // if nothing in the extern that we can use // then set array to current symbol only if(StringLen(Pairs)<6) { Pairz[0]=Symbol(); ptrPMAX=1; break; } //save the old comma pcomma=comma; // find the next comma comma=StringFind(Pairs, ",", pcomma+1); // Gather trailing pair (no comma following last pair) // then leave (accounts for one pair on line) if(comma<0) { Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma); ptrPMAX=ipair; Print(ipair+" "+Pairz[ipair]); break; } // store the pair into an array if(ipair==0) Pairz[ipair]=StringSubstr(Pairs, pcomma, comma-pcomma); if(ipair >0) Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma-1); Print(ipair+" "+Pairz[ipair]); // increment pointer for next elemant ipair++; if(ipair>100) break; } Comment(" "); logwrite(TradeComment,"Init Complete"); } //+----------------+ //| Custom DE-init | //+----------------+ // Called ONCE when EA is removed from chart int deinit() { // always indicate deinit statistics logwrite(TradeComment,"MAX number of orders "+maxOrders); Comment(" "); logwrite(TradeComment,"DE-Init Complete"); } //+-----------+ //| Main | //+-----------+ // Called EACH TICK and each Bar[] int start() { // The following MUST be done before anything else // step through each pair, once a tick ptrPairz++; if(ptrPairz>=ptrPMAX) ptrPairz=0; mySymbol=Pairz[ptrPairz]; Comment("Now trading -"+mySymbol+"- at position "+ptrPairz ); // get normalized Point based on Broker decimal places // every tick, since we may be using multi-pairs myPoint = SetPoint(); // end 'MUST' int cnt=0; int gle=0; int ticket=0; int OrdersPerSymbol=0; // stoploss and takeprofit and close control double SL=0; double TP=0; double CurrentProfit=0; double CurrentBasket=0; // direction control bool BUYme=false; bool SELLme=false; double MaCurrent; double MaPrevious; //safety counter int loopcount=0; OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++; } // keep some statistics if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol; //uncomment for MULTIPLE trades per bar //if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true; // bar counting if(bartime[ptrPairz]!=iTime(mySymbol, PERIOD_D1, 0) ) { bartime[ptrPairz]=iTime(mySymbol, PERIOD_D1, 0) ; //uncomment for SINGLE trade per bar if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true; //+-----------------------------+ //| Code here will execute once | //| at the OPEN of a NEW BAR | //| | //| NOTE: use 'tf1' for any | //| indicator or iCustom | //| timeframe parameter | //+-----------------------------+ double RSI1=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,1); double RSI2=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,2); double RSI3=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,3); if(WithTrend==false && RSI3<50 && RSI250 && RSI2>RSI3 && RSI1>RSI2) SELLme=true; if(WithTrend==true && RSI1<50 && RSI250 && RSI2>RSI3 && RSI1>RSI2) BUYme=true; //+------------+ //| End Insert | //+------------+ } //+-----------------------------+ //| Insert your indicator here | //| And set either BUYme or | //| SELLme true to place orders | //| | //| NOTE: use 'tf1' for any | //| indicator or iCustom | //| timeframe parameter | //+-----------------------------+ //+------------+ //| End Insert | //+------------+ //ENTRY LONG (buy, Ask) if( TradeAllowed[ptrPairz] && BUYme) { OpenBuy(); } //ENTRY SHORT (sell, Bid) if( TradeAllowed[ptrPairz] && SELLme) { OpenSell(); } // // Order Management // //Basket profit // Basket profit or loss - count the profit/loss // from this EA & Symbol()& magicnumber only // calculation can be done in PIPS or DOLLARS CurrentBasket=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) { // add up pips //if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( Close[0]-OrderOpenPrice() ); //if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( (Close[0]-OrderOpenPrice()) * (-1) ); //add up dollars if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( OrderProfit() ); if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( OrderProfit() ); } } for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber ) { if(OrderType()==OP_BUY) { bid=MarketInfo(mySymbol,MODE_BID); CurrentProfit=(bid-OrderOpenPrice()) ; // // Modify for break even //======================= // // OrderStopLoss will be equal to OrderOpenPrice if this event happens // thus it will only ever get executed one time per ticket if( BreakEven>0 ) { if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()>OrderStopLoss()) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); SL=OrderOpenPrice()+(ask-bid); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY BUY BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY BUY BE Bid="+Bid+" error="+gle+" "+ErrorDescription(gle)); } } } // // check for trailing stop //========================= // // This starts trailing after 'TrailStop' pips of profit if( TrailStop>0 && iClose(mySymbol,PERIOD_D1,0)>OrderOpenPrice()+(TrailStop*myPoint) ) { bid=MarketInfo(mySymbol,MODE_BID); if( OrderStopLoss() < bid-(TrailStop*myPoint) ) { SL=bid-(TrailStop*myPoint); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY BUY TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY BUY TS Bid="+bid+" error="+gle+" "+ErrorDescription(gle)+" "); } } } // Did we make a profit //====================== if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint)) { CloseBuy("PROFIT"); } // Did we take a loss //==================== if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint)) { CloseBuy("LOSS"); } } // if BUY if(OrderType()==OP_SELL) { ask=MarketInfo(mySymbol,MODE_ASK); CurrentProfit=(OrderOpenPrice()-ask); //logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/myPoint+" CurrentBasket="+CurrentBasket/myPoint); // // Modify for break even //======================= // // OrderStopLoss will be equal to OrderOpenPrice if this event happens // thus it will only ever get executed one time per ticket if( BreakEven>0 ) { if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()0 && iClose(mySymbol,PERIOD_D1,0) ask+(TrailStop*myPoint) ) { SL=ask+(TrailStop*myPoint); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY SELL TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY SELL TS Ask="+ask+" error="+gle+" "+ErrorDescription(gle)); } } } // Did we make a profit //====================== if( ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint) ) { CloseSell("PROFIT"); } // Did we take a loss //==================== if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint) ) { CloseSell("LOSS"); } } //if SELL } // if(OrderSymbol) } // for } // start() // log data to a file name passed in // print everything regardless of log setting void logwrite (string filename, string mydata) { int myhandle; string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS); Print(" "+mySymbol+" "+mydata+" "+gregorian); // don't log anything if testing or if user doesn't want it if(IsTesting()) return(0); if(KillLogging) return(0); myhandle=FileOpen(mySymbol+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";"); if(myhandle>0) { FileSeek(myhandle,0,SEEK_END); FileWrite(myhandle, " "+mySymbol+" "+mydata+" "+gregorian); FileClose(myhandle); } } //ENTRY LONG (buy, Ask) void OpenBuy() { int gle=0; int ticket=0; double SL=0; double TP=0; int loopcount; // PLACE order is independent of MODIFY order. // This is mandatory for ECNs and acceptable for retail brokers loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // place order - NO TP OR SL ticket=OrderSend(mySymbol,OP_BUY,Lots,ask,Slippage,0,0,TradeComment,MagicNumber,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+ask+" Lots="+Lots); TradeAllowed[ptrPairz]=false; break; } else { logwrite(TradeComment,"-----ERROR----- Placing BUY order: Lots="+Lots+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); // give up after loopcount tries loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing BUY order"); return(gle); } } }//while - place order // modify the order for users TP & SL loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // don't set TP and SL both to zero, they're already there if(LossLimit==0 && ProfitMade==0) break; if(LossLimit ==0) SL=0; if(ProfitMade ==0) TP=0; if(LossLimit >0) SL=ask-((LossLimit+LL2SL)*myPoint ); if(ProfitMade >0) TP=ask+((ProfitMade+LL2SL)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"BUY OPENMOD Ticket="+ticket+" Ask="+ask+" Lots="+Lots+" SL="+SL+" TP="+TP); break; } else { logwrite(TradeComment,"-----ERROR----- Modifying BUY order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on modifying BUY order"); return(gle); } } }//while - modify order }//BUYme //ENTRY SHORT (sell, Bid) void OpenSell() { int gle=0; int ticket=0; double SL=0; double TP=0; int loopcount; // PLACE order is independent of MODIFY order. // This is mandatory for ECNs and acceptable for retail brokers loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); ticket=OrderSend(mySymbol,OP_SELL,Lots,bid,Slippage,0,0,TradeComment,MagicNumber,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+bid+" Lots="+Lots); TradeAllowed[ptrPairz]=false; break; } else { logwrite(TradeComment,"-----ERROR----- placing SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order"); return(gle); } } }//while // modify the order for users TP & SL loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // don't set TP and SL both to zero, they're already there if(LossLimit==0 && ProfitMade==0) break; if(LossLimit ==0) SL=0; if(ProfitMade ==0) TP=0; if(LossLimit >0) SL=bid+((LossLimit+LL2SL)*myPoint ); if(ProfitMade >0) TP=bid-((ProfitMade+LL2SL)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"SELL OPENMOD Ticket="+ticket+" Bid="+bid+" Lots="+Lots+" SL="+SL+" TP="+TP); break; } else { logwrite(TradeComment,"-----ERROR----- modifying SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order"); return(gle); } } }//while }//SELLme void CloseBuy (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string bTK=" Ticket="+OrderTicket(); string bSL=" SL="+OrderStopLoss(); string bTP=" TP="+OrderTakeProfit(); string bPM; string bLL; string bER; bPM=" PM="+ProfitMade; bLL=" LL="+LossLimit; while(true) { bid=MarketInfo(mySymbol,MODE_BID); OrderClose(OrderTicket(),OrderLots(),bid,Slippage,White); gle=GetLastError(); bER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+bid+ bTK + bSL + bTP + bPM + bLL); RefreshRates(); Sleep(500); } loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on closing BUY order"); return(gle); } }//while } void CloseSell (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string sTK=" Ticket="+OrderTicket(); string sSL=" SL="+OrderStopLoss(); string sTP=" TP="+OrderTakeProfit(); string sPM; string sLL; string sER; sPM=" PM="+ProfitMade; sLL=" LL="+LossLimit; while(true) { ask=MarketInfo(mySymbol,MODE_ASK); OrderClose(OrderTicket(),OrderLots(),ask,Slippage,Red); gle=GetLastError(); sER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+ask+ sTK + sSL + sTP + sPM + sLL); RefreshRates(); Sleep(500); } loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order"); return(gle); } }//while } // Function to correct the value of Point // for brokers that add an extra digit to price // Courtesy of Robert Hill double SetPoint() { double mPoint; int digits=MarketInfo(mySymbol,MODE_DIGITS); if (digits < 4) { mPoint = 0.01; } else { mPoint = 0.0001; } return(mPoint); }